
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using M0;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Object = UnityEngine.Object;

public static partial class M
{
    public const string EventKey_切换场景 = "EventKey_切换场景";
    public const string EventKey_游戏结束 = "EventKey_游戏结束";
    public const string EventKey_游戏开始 = "EventKey_游戏开始";
    public const string EventKey_设游戏模式 = "EventKey_设游戏模式";



    public static async void 异步动画(Vector3 v3begin, Vector3 v3end, float time, Action<Vector3> dowhat,Action endCall)
    {
        float curTime = 0;
        while (curTime<=time)
        {
            Vector3 cur = Vector3.Lerp(v3begin, v3end, curTime / time);
            dowhat(cur);
            await Task.Yield();
            curTime += Time.deltaTime;
        }
        dowhat(v3end);
        endCall?.Invoke();
    }
    public static async Task 异步等待(float f)
    {
        float w = 0f;
        while (w<f)
        {
            w += Time.deltaTime;
            await Task.Yield();
        }
        
        return;
    }
    
    public static void 播放广告(string 广告目的,Action<bool> call)
    {
        Debug.Log("播放广告");
        call?.Invoke(true);
    }
    
    public static async void 切换场景(string sceneName)
    {
        await SceneManager.LoadSceneAsync(sceneName);
        Event.DoEvent(EventKey_切换场景,sceneName);
    }


    public static bool NullOrEmpty(this string s)
    {
        return string.IsNullOrEmpty(s);
    }



    public static void 保存缓存(string key,string content)
    {
        Boot.Instance.Get小游戏.保存数据(key,content);
    }

    public static T Get缓存<T>(string key) where T:new()
    {
        int a=0;
        string content="";
        Boot.Instance.Get小游戏.Get本地缓存<string>(key,ref a,ref content);
        if (string.IsNullOrEmpty(content))
        {
            return new T();
        }
        T res = JsonConvert.DeserializeObject<T>(content);
        return res;
    }
    // public static bool TryAdd<T, M>(this Dictionary<T, M> dict, T key, M value)
    // {
    //     if(dict)
    // }


    /// <summary>
    /// list 深拷贝
    /// </summary>
    /// <param name="res"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static List<T> CopyList<T>(this List<T> res)
    {
        List<T> r = new List<T>();
        foreach (var VARIABLE in res)
        {
            r.Add(VARIABLE);
        }
        return r;
    }

    public static JsonV3 ToV3(this Vector3 v3)
    {
        JsonV3 v = new JsonV3() {x = v3.x, y = v3.y, z = v3.z};
        return v;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public static bool 点到Ui(int 参考=0)
    {
        var eventDataCurrentPosition = new PointerEventData(EventSystem.current);
        eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
        
        GraphicRaycaster graphicRaycaster = Object.FindObjectOfType<GraphicRaycaster>();
        List<RaycastResult> results = new List<RaycastResult>();
        graphicRaycaster.Raycast(eventDataCurrentPosition, results); // 执行射线投射，获取结果列表
        
        return results.Count > 参考; // 如果有结果，则表示点击在UI元素上
    }

    // private static RaycastHit[] hitResults = new RaycastHit[];
    private static RaycastHit[] hitResults = new RaycastHit[10];
    public static T 射线检测<T>(Ray ray)
    {
        // RaycastHit[] hitResults = new RaycastHit[10];
        var numHits = Physics.RaycastNonAlloc(ray, hitResults);
        float 最短距离 = float.MaxValue;
        T res = default(T);
        if (numHits > 0)
        {
            for (int i = 0; i < numHits; i++)
            {
                // 输出碰撞到的物体的名字
                // Debug.Log("Hit " + hitResults[i].collider.name);
 
                // 如果需要，可以在这里执行更多操作，例如改变物体颜色等
                if (hitResults[i].collider == null) continue;
            
                T 组件 = hitResults[i].collider.gameObject.GetComponent<T>();
                if (组件 != null)
                {
                    float 距离 = hitResults[i].distance;
                    if (距离 < 最短距离)
                    {
                        最短距离 = 距离;
                        res = 组件;
                    }
                }
            }
        }

        return res;
    }
    
    
    
    ///修改锚点
    private static void SetAnchors(this RectTransform rect,AnchorType type)
    {
        switch (type)
        {
            case AnchorType.TopCenter:
                rect.anchorMin = new Vector2(0.5f, 1);
                rect.anchorMax = new Vector2(0.5f, 1);
                break;
            case AnchorType.MidCenter:
                rect.anchorMin = new Vector2(0.5f, 0.5f);
                rect.anchorMax = new Vector2(0.5f, 0.5f);
                break;
            case AnchorType.FixFix:
                rect.anchorMin = new Vector2(0, 0f);
                rect.anchorMax = new Vector2(1f, 1f);
                break;
            case AnchorType.TopLeft:
                rect.anchorMin = new Vector2(0, 1f);
                rect.anchorMax = new Vector2(0f, 1f);
                break;
        }
    }

    public static async Task 动态修改锚点(this RectTransform rect, AnchorType type, Vector2 pivot)
    {
        rect.pivot = pivot;
        await Task.Yield();
        Debug.Log(rect.name);
        Debug.Log(rect.anchoredPosition);
        rect.SetAnchors(type);
        
    }

    public static AnchorType 检查锚点(this RectTransform rect)
    {
        if (rect.anchorMin.x.CompareTo(0.5f) == 0 && rect.anchorMin.y.CompareTo(1f) == 0 &&
            rect.anchorMax.x.CompareTo(0.5f) == 0 && rect.anchorMax.y.CompareTo(1f) == 0)
        {
            return AnchorType.TopCenter;
        }else if (rect.anchorMin.x.CompareTo(0.5f) == 0 && rect.anchorMin.y.CompareTo(0.5f) == 0 &&
                  rect.anchorMax.x.CompareTo(0.5f) == 0 && rect.anchorMax.y.CompareTo(0.5f) == 0)
        {
            return AnchorType.MidCenter;
        }else if (rect.anchorMin.x.CompareTo(0) == 0 && rect.anchorMin.y.CompareTo(0) == 0 &&
                  rect.anchorMax.x.CompareTo(1) == 0 && rect.anchorMax.y.CompareTo(1) == 0)
        {
            return AnchorType.FixFix;
        }
        else if (rect.anchorMin.x.CompareTo(0) == 0 && rect.anchorMin.y.CompareTo(1) == 0 &&
                 rect.anchorMax.x.CompareTo(0) == 0 && rect.anchorMax.y.CompareTo(1) == 0)
        {
            return AnchorType.TopLeft;
        }
        
        return AnchorType.MidCenter;
    }
    
    public enum AnchorType
    {
        TopCenter,
        TopLeft,
        TopRight,
        MidCenter,
        MidLeft,
        MidRight,
        BottomCenter,
        BottomLeft,
        BottomRight,
        FixFix,
    }


    public static void 递归执行Tranform(this Transform tran ,Action<Transform> 处理)
    {
        
    }
    public static List<T> 递归执行Tranform<T>(this Transform tran ,Func<Transform,T> 处理)
    {
        List<T> res = new List<T>();
        处理递归(tran, ref res);
        

        void 处理递归(Transform tr, ref List<T> r)
        {
            if (r == null)
            {
                r = new List<T>();
            }

            T get = 处理.Invoke(tr);
            r.Add(get);
            if (tr.childCount > 0)
            {
                for (int i = 0; i < tr.childCount; i++)
                {
                    处理递归(tr.GetChild(i), ref r);
                }
            }
        }

        return res;
    }
    
    /// <summary>
    /// 单例-----------------------------------
    /// </summary>
    public static MyEvent Event
    {
        get
        {
            return MyEvent.Instance;
        }
    }
    
    public static Resource加载 Resource
    {
        get
        {
            return Resource加载.Instance;
        }
    }
    
    public static Mono缓存池 缓存{get{return Mono缓存池.Instance;}}
}
